package com.example.fresh_market.fragments;

import android.app.AlertDialog;
import android.support.v4.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

import com.android.volley.Request;
import com.example.fresh_market.R;
import com.example.fresh_market.activity.CreateOrderActivity;
import com.example.fresh_market.adapter.CartAdapter;
import com.example.fresh_market.constants.StrConstant;
import com.example.fresh_market.databinding.FragmentCartBinding;
import com.example.fresh_market.entity.Cart;
import com.example.fresh_market.request.ApiResponse;
import com.example.fresh_market.request.PageResult;
import com.example.fresh_market.request.PreOrderDetail;
import com.example.fresh_market.request.PreOrderReq;
import com.example.fresh_market.utils.HttpUtil;
import com.example.fresh_market.utils.ToastUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.http.Header;
import lombok.NoArgsConstructor;

@NoArgsConstructor
public class CartFragment extends Fragment {
    private Context mContext;
    private FragmentCartBinding binding;
    private TextView totalPrice_tv;
    private SharedPreferences preferences;
    private CartAdapter cartAdapter;
    private String token;
    private AlertDialog cartNumDialog;
    private EditText cartNum;
    private Button cartNumOk;


    public static CartFragment newInstance() {
        CartFragment myFragment = new CartFragment();
        Bundle args = new Bundle();
        myFragment.setArguments(args);
        return myFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mContext = getContext();
        binding = FragmentCartBinding.inflate(inflater, container, false);
        View view = binding.getRoot();
        RecyclerView cart_item_list = view.findViewById(R.id.cart_item_list);
        LinearLayoutManager llM = new LinearLayoutManager(mContext);
        cart_item_list.setLayoutManager(llM);
        preferences = mContext.getSharedPreferences(StrConstant.CONFIG, Context.MODE_PRIVATE);
        token = preferences.getString(StrConstant.TOKEN, "");
        Map<String, String> headers = Map.of(HttpUtil.Auth, token,
                Header.CONTENT_TYPE.getValue(), "application/x-www-form-urlencoded;charset=UTF-8");
        cartAdapter = new CartAdapter(new ArrayList<>(), new CartAdapter.MyClickListener() {
            @Override
            public void onAddClick(View v, int position) {
                Cart cart = cartAdapter.getItem(position);
                requestCartUpdate(Request.Method.POST, cart, headers, String.valueOf(1), () -> {
                    cart.setProductNum(cart.getProductNum() + 1);
                    cartAdapter.updateItem(position, cart);
                    if (cart.isChecked()) {
                        BigDecimal decimal = new BigDecimal(StringUtils.substringBefore(totalPrice_tv.getText().toString(), "元"));
                        totalPrice_tv.setText(String.format("%s元", decimal.add(cart.getProductPrice())));
                    }
                });
            }

            @Override
            public void onSubClick(View v, int position) {
                Cart cart = cartAdapter.getItem(position);
                if (cart.getProductNum() > 1) {
                    requestCartUpdate(Request.Method.POST, cart, headers, String.valueOf(-1), () -> {
                        cart.setProductNum(cart.getProductNum() - 1);
                        cartAdapter.updateItem(position, cart);
                        if (cart.isChecked()) {
                            BigDecimal decimal = new BigDecimal(StringUtils.substringBefore(totalPrice_tv.getText().toString(), "元"));
                            totalPrice_tv.setText(String.format("%s元", decimal.subtract(cart.getProductPrice())));
                        }
                    });
                } else {
                    deleteOpt("是否要删除该商品？", List.of(cart), position);
                }
            }

            @Override
            public void onCheckBoxClick(View v, int position) {
                List<Cart> carts = cartAdapter.getAllItems();
                Cart currentClick = carts.get(position);
                if (currentClick.isChecked()) {
                    binding.cartSelectAll.setChecked(false);
                }
                currentClick.setChecked(!currentClick.isChecked());
                BigDecimal totalPrice = new BigDecimal("0.00");
                int checkedCount = 0;
                for (Cart cart : carts) {
                    if (cart.isChecked()) {
                        checkedCount++;
                        totalPrice = totalPrice.add(cart.getProductPrice().multiply(BigDecimal.valueOf(cart.getProductNum())));
                    }
                }
                if (checkedCount == carts.size()) {
                    binding.cartSelectAll.setChecked(true);
                }
                totalPrice_tv.setText(String.format("%s元", totalPrice));
            }

            @Override
            public void onCartNumClick(View v, int position) {
                Cart cart = cartAdapter.getItem(position);
                if (cartNumDialog == null) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                    View cartNumView = inflater.inflate(R.layout.dialog_cart_num, null, false);
                    builder.setView(cartNumView);
                    builder.setCancelable(false);
                    cartNumDialog = builder.create();
                    cartNum = cartNumView.findViewById(R.id.cart_num);
                    Button minus = cartNumView.findViewById(R.id.cart_num_minus);
                    minus.setOnClickListener(view -> {
                        int parseInt = Integer.parseInt(cartNum.getText().toString());
                        if (parseInt == 2) {
                            minus.setEnabled(false);
                        }
                        cartNum.setText(String.valueOf(parseInt - 1));
                    });
                    cartNumView.findViewById(R.id.cart_num_plus).setOnClickListener(view -> {
                        int parseInt = Integer.parseInt(cartNum.getText().toString());
                        cartNum.setText(String.valueOf(parseInt + 1));
                        if (parseInt > 1) {
                            minus.setEnabled(true);
                        }
                    });
                    cartNumView.findViewById(R.id.cart_num_cancel).setOnClickListener(view -> {
                        cartNumDialog.dismiss();
                    });
                    cartNumOk = cartNumView.findViewById(R.id.cart_num_ok);
                }
                cartNumOk.setOnClickListener(view -> {
                    requestCartUpdate(Request.Method.PUT, cart, headers, cartNum.getText().toString(), () -> {
                        int origin = cart.getProductNum();
                        cart.setProductNum(Integer.parseInt(cartNum.getText().toString()));
                        cartAdapter.updateItem(position, cart);
                        if (cart.isChecked()) {
                            BigDecimal decimal = new BigDecimal(StringUtils.substringBefore(totalPrice_tv.getText().toString(), "元"));
                            BigDecimal subtract = decimal.subtract(cart.getProductPrice().multiply(BigDecimal.valueOf(origin)));
                            totalPrice_tv.setText(String.format("%s元", subtract.add(cart.getProductPrice().multiply(BigDecimal.valueOf(cart.getProductNum())))));
                        }
                        cartNumDialog.dismiss();
                    });
                });
                cartNum.setText(String.valueOf(cart.getProductNum()));
                cartNumDialog.show();
            }
        });
        binding.cartSelectAll.setOnClickListener(v -> {
            boolean isChecked = binding.cartSelectAll.isChecked();
            BigDecimal totalPrice = new BigDecimal("0.00");
            List<Cart> carts = new ArrayList<>(cartAdapter.getAllItems());
            for (int i = 0; i < carts.size(); i++) {
                Cart cart = carts.get(i);
                if (isChecked) {
                    totalPrice = totalPrice.add(cart.getProductPrice().multiply(BigDecimal.valueOf(cart.getProductNum())));
                }
                cart.setChecked(isChecked);
            }
            cartAdapter.setData(carts);
            totalPrice_tv.setText(String.format("%s元", totalPrice));
        });
        initCartData();
        cart_item_list.setAdapter(cartAdapter);
        totalPrice_tv = view.findViewById(R.id.textView_cost);
        ImageButton BT_delete = view.findViewById(R.id.button_delete);
        Button BT_buy = view.findViewById(R.id.button_buy);
        // 清空购物车
        BT_delete.setOnClickListener(v -> {
            if (cartAdapter.getItemCount() == 0) {
                ToastUtil.showToast(mContext, "请先添加商品");
                return;
            }
            deleteOpt("您确定要清空购物车吗？", cartAdapter.getAllItems(), -1);
        });
        // 点击结算
        BT_buy.setOnClickListener(v -> {
            if (cartAdapter.getItemCount() == 0) {
                ToastUtil.showToast(mContext, "请先添加商品");
                return;
            }
            Gson gson = new Gson();
            List<PreOrderDetail> orderDetails = cartAdapter.getPreOrderDetails();
            if (orderDetails.isEmpty()) {
                ToastUtil.showToast(mContext, "请先选择商品");
                return;
            }
            PreOrderReq preOrderReq = PreOrderReq.builder()
                    .preOrderType("shoppingCart")
                    .orderDetails(orderDetails)
                    .build();
            Intent intent = new Intent(mContext, CreateOrderActivity.class);
            intent.putExtra("preOrderReq", gson.toJson(preOrderReq));
            startActivity(intent);
        });
        return view;
    }

    private void deleteOpt(String message, List<Cart> cartList, int index) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("操作提示")
                .setMessage(message)
                .setPositiveButton("是", (dialogInterface, which) -> {
                    StringBuilder url = new StringBuilder("/usr/cart?");
                    for (Cart cart : cartList) {
                        url.append("ids=").append(cart.getId()).append("&");
                    }
                    HttpUtil.delete(mContext, url.toString(), (response) -> {
                        ApiResponse apiResponse = new Gson().fromJson(response, ApiResponse.class);
                        if (apiResponse.getCode() == 200) {
                            ToastUtil.showToast(mContext, "操作成功");
                            cartAdapter.removeData(index);
                        }
                    });
                    dialogInterface.dismiss();
                })
                .setNegativeButton("否", (dialogInterface, which) -> dialogInterface.cancel());
        // 创建并显示对话框
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    private void initCartData() {
        binding.cartSelectAll.setChecked(false);
        HttpUtil.get(mContext, "/usr/cart?page=1&size=100000",
                Map.of(HttpUtil.Auth, token),
                response -> {
                    ApiResponse<PageResult<Cart>> res = new Gson().fromJson(response, new TypeToken<ApiResponse<PageResult<Cart>>>() {
                    }.getType());
                    if (res.getCode() == 200) {
                        cartAdapter.setData(res.getData().getList());
                        totalPrice_tv.setText(String.format("%s元", "0.00"));
                    }
                });
    }

    private void requestCartUpdate(int method, Cart cart, Map<String, String> headers,
                                   String number, Runnable extra) {
        Map<String, String> params = new HashMap<>();
        params.put("id", String.valueOf(cart.getId()));
        params.put("productId", String.valueOf(cart.getProductId()));
        params.put("productNum", number);
        HttpUtil.sendRequest(method, mContext, "/usr/cart", headers, params, response -> {
            ApiResponse res = new Gson().fromJson(response, ApiResponse.class);
            if (res.getCode() == 200) {
                extra.run();
            }
        }, HttpUtil.getCommonErrorListener(mContext));
    }

    @Override
    public void onResume() {
        super.onResume();
        initCartData();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            initCartData();
        }
    }
}